package org.displayextended
{
	import flash.display.MovieClip;
	import flash.events.Event;
	
	import org.event.BuildCompleteEvent;

	 /**
	 * AniMovSprite
	 * 
	 * Extends MovSprite w/ Animation BuildIn/BuildOut and Modal Capability
	 * 
	 * Target MovieClip:
	 * - Can use an external asset OR stage instance
	 * 
	 * Animation BuildIn/BuildOut:
	 * - Depends on default, buildIn, buildOut frame labeling
	 * - Dispatches BuildCompleteEvents on both in/out
	 * - Toggle animation with property animateBuild (Boolean)
	 * 
	 * Modal Capability:
	 * - If animateBuild == false, will create a Modal or use a provided background instance in the target MovieClip
	 * - If animateBuild == true, it is currently assumed you will be providing Modal background via your animation
	 * - When used with AniMovSpriteManager, Modals will not be switched out but built on top of
	 * 
	 * This class should be extended for more advanced functionlity or to encapsulate custom label Constants, etc...
	 * 
	 * Usage:
	 * 
	 * 1) Initialize Class with Asset OR Stage Instance:
	 * 
	 * 	var window:AniMovSprite = new AniMovSprite( 'path.to.some.asset'[ OR  somechildmc.button ] );
	 * 	addChild( window );
	 * 
	 * 2) Set properties if need be, (labels, etc) defaults work fine & should be used where possible
	 * 	
	 * 	window.animateBuild = false;
	 * 	window.defaultLabel = 'someLabel';
	 *
	 * 3) Add listeners in parent class for clicks and buildCompletes
	 * 
	 * 	window.addEventListener( BuildCompleteEvent.BUILD_IN_COMPLETE, onWindowBuildInComplete );
	 * 	window.addEventListener( BuildCompleteEvent.BUILD_OUT_COMPLETE, onWindowBuildOutComplete );
	 * 
	 * 4) Display it (whether animated or not)
	 * 
	 * 	window.buildIn();
	 * 
	 * @author zachary.seabrook
	*/
	public class AniMovSprite extends MovSprite
	{
		private static var TYPE_STRING				:String		= 'string';
		
		public 	static var DEFAULT_ANIMATE_BUILD	:Boolean 	= true;
		public 	static var DEFAULT_BUILD_IN_LABEL	:String 	= 'buildIn';
		public 	static var DEFAULT_BUILD_OUT_LABEL	:String 	= 'buildOut';
		public 	static var DEFAULT_DEFAULT_LABEL	:String 	= 'default';
		public 	static var DEFAULT_IS_MODAL			:Boolean 	= false;
		public 	static var DEFAULT_USE_MODAL_INSTANCE:Boolean 	= false;
		public 	static var DEFAULT_MODAL_INSTANCE_NAME:String 	= 'background';
		public 	static var DEFAULT_MODAL_ALPHA:Number			= .9;
		
		private var _animateBuild		:Boolean;
		private var _animateBuildSet	:Boolean;
		private var _buildInLabel		:String;
		private var _buildOutLabel		:String;
		private var _defaultLabel		:String;
		private var _isModal			:Boolean;
		private var _isModalSet			:Boolean;
		private var _useModalInstance	:Boolean;
		private var _useModalInstanceSet:Boolean;
		private var _modalInstanceName	:String;
		private var _modalAlpha			:Number;
		
		/**
		 * Constructor
		 * @see MovSprite (super class)
		 * 
		 * @param movieClipClassPathOrInstance (string or movieclip)!
		 */		
		public function AniMovSprite( movieClipClassPathOrInstance:Object=null )
		{
			// turn tracing off by default
			showTrace = false;
			
			if( typeof( movieClipClassPathOrInstance ) == TYPE_STRING )
			{
				super( movieClipClassPathOrInstance as String );
			}
			else if( movieClipClassPathOrInstance )
			{
				mc = movieClipClassPathOrInstance as MovieClip;
			}
			
			visible = false;
		}
		
		/* public function get superClass():Object { return super; }
		
		public function test():String { return 'super here'; } */
		
		/**
		 * Builds In the MovieClip
		 */		
		public function buildIn():void
		{
			t( '[AniMovSprite] buildIn' );
			
			visible = true;
			
			if( animateBuild )
			{
				gotoAndPlay( buildInLabel );
				startFrameMonitoring();
			}
			else
			{
				if( isModal && useModalInstance )
					mc[ modalInstanceName ].alpha = modalAlpha;
				
				gotoAndStop( defaultLabel );
				onBuildInComplete();
			}
		}
		
		public function buildOut():void
		{
			t( '[AniMovSprite] buildOut' );
			
			if( animateBuild )
			{
				gotoAndPlay( buildOutLabel );
				startFrameMonitoring();
			}
			else
			{
				onBuildOutComplete();
			}
		}
		
		protected function startFrameMonitoring():void
		{
			t( '[AniMovSprite] startFrameMonitoring' );
			addEventListener( Event.ENTER_FRAME, doFrameMonitor );
		}
		
		protected function doFrameMonitor( event:Event ):void
		{
			//t( '[AniMovSprite] doFrameMonitor', currentFrame, totalFrames, currentLabel, defaultLabel );
			
			if( currentFrame == totalFrames )
			{
				onBuildOutComplete()
				endFrameMonitoring();
			}
			
			if( currentLabel == defaultLabel )
			{
				if( isModal && useModalInstance )
					mc[ modalInstanceName ].alpha = modalAlpha;
				
				onBuildInComplete();
				endFrameMonitoring();
			}
		}
		
		protected function endFrameMonitoring():void
		{
			//t( '[AniMovSprite] endFrameMonitoring', currentFrame, currentLabel );
			removeEventListener( Event.ENTER_FRAME, doFrameMonitor );
		}
		
		protected function onBuildInComplete():void
		{
			t( '[AniMovSprite] onBuildInComplete' );
			dispatchEvent( new BuildCompleteEvent( BuildCompleteEvent.BUILD_IN_COMPLETE ) );
		}
		
		protected function onBuildOutComplete():void
		{
			t( '[AniMovSprite] onBuildOutComplete' );
			visible = false;
			dispatchEvent( new BuildCompleteEvent( BuildCompleteEvent.BUILD_OUT_COMPLETE ) );
		}
		
		// Class Property Getter/Setters
		
		public function get animateBuild():Boolean
		{
			if( !_animateBuildSet )
				animateBuild = DEFAULT_ANIMATE_BUILD;
			
			return _animateBuild;
		}
		
		public function set animateBuild( val:Boolean ):void
		{
			_animateBuild = val;
			_animateBuildSet = true;
		}
		
		public function get buildInLabel():String
		{
			if( !_buildInLabel )
				_buildInLabel = DEFAULT_BUILD_IN_LABEL;
			
			return _buildInLabel;
		}
		
		public function set buildInLabel( val:String ):void
		{
			_buildInLabel = val;
		}
		
		public function get buildOutLabel():String
		{
			if( !_buildOutLabel )
				_buildOutLabel = DEFAULT_BUILD_OUT_LABEL;
			
			return _buildOutLabel;
		}
		
		public function set buildOutLabel( val:String ):void
		{
			_buildOutLabel = val;
		}
		
		public function get defaultLabel():String
		{
			if( !_defaultLabel )
				_defaultLabel = DEFAULT_DEFAULT_LABEL;
			
			return _defaultLabel;
		}
		
		public function set defaultLabel( val:String ):void
		{
			_defaultLabel = val;
		}
		
		public function get isModal():Boolean { 
			if(!_isModalSet){ isModal = DEFAULT_IS_MODAL; }
			return _isModal;
		}
		
		public function set isModal( val:Boolean ):void { 
			_isModal = val;
			_isModalSet = true;
		}
		
		public function get useModalInstance():Boolean { 
			if(!_useModalInstanceSet){ useModalInstance = DEFAULT_USE_MODAL_INSTANCE; }
			return _useModalInstance;
		}
		
		public function set useModalInstance( val:Boolean ):void { 
			_useModalInstance = val;
			_useModalInstanceSet = true;
		}
		
		public function get modalInstanceName():String { 
			if(!_modalInstanceName){ modalInstanceName = DEFAULT_MODAL_INSTANCE_NAME; }
			return _modalInstanceName;
		}
		
		public function set modalInstanceName( val:String ):void { 
			_modalInstanceName = val;
		}
		
		public function get modalAlpha():Number { 
			if(!_modalAlpha){ modalAlpha = DEFAULT_MODAL_ALPHA; }
			return _modalAlpha;
		}
		
		public function set modalAlpha( val:Number ):void { 
			_modalAlpha = val;
		}
	}
}